using System.Net;

namespace Framework.Network
{
    public class MoonConnection : BaseConnection
    {
        //two bytes len head
        private const int headLength = sizeof(ushort);
        private readonly byte[] head = new byte[headLength];

        private const ushort MESSAGE_CONTINUED_FLAG = ushort.MaxValue;

        private NetBuffer buffer = null;
        
        public override void Start()
        {
            ReadHead();
        }

        public override bool Send(NetBuffer data)
        {
            short length = (short)data.Count;
            length = IPAddress.HostToNetworkOrder(length);
            data.WriteFront(length);
            return base.Send(data);
        }

        private void ReadHead()
        {
            ReadAsync(head, 0, headLength, (bytesTransferred, e) =>
            {
                if (e != null)
                {
                    OnError(e);
                    return;
                }

                ushort size = (ushort)IPAddress.NetworkToHostOrder(NetUtil.ToInt16(head));
                ReadBody(size, size < MESSAGE_CONTINUED_FLAG);
            });
        }

        private void ReadBody(ushort size, bool fin)
        {
            if (buffer == null)
                buffer = new NetBuffer(fin ? size : 5 * size);
            else
                buffer.Prepare(size);
            
            ReadAsync(buffer.Data, buffer.WritePos, size, (bytesTransferred, e) =>
            {
                if (e != null)
                {
                    OnError(e);
                    return;
                }
                
                buffer.Commit(bytesTransferred);
                
                if (fin)
                {
                    SocketMessage message = new(ConnectId, SocketMessageType.Message, buffer, 0);
                    buffer = null;
                    HandleMessage(message);
                }
                
                ReadHead();
            });
        }
    }
}